﻿package com.moonshineproject.plugin.globalerrorhandling {
	import flash.display.GradientType;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	public class GEHDisplay extends Sprite {
		public static const CONTINUE:String = "continue";
		public static const DISMISS_ALL:String = "dismissAll";
		public static const BUG_REPORT:String = "bugReport";
		public static const PASTEBIN:String = "pastebin";
		
		private var title:TextField = new TextField();
		private var errorDisplay:Sprite = new Sprite();
		private var errors:Vector.<GEHError> = new Vector.<GEHError>();
		private var selected:GEHError;
		private var buttonBar:Sprite = new Sprite();
		
		private var discardedTxt:TextField = new TextField();
		private var discardedHighlight:Sprite = new Sprite();
		
		private var continueBtn:GEHButton = new GEHButton("Continue");
		private var dismissBtn:GEHButton = new GEHButton("Dismiss all");
		private var bugReportBtn:GEHButton = new GEHButton("Submit bug report");
		private var pastebinBtn:GEHButton = new GEHButton("Pastebin");
		
		private var w:Number = 600;
		private var h:Number = 680;
		
		private var maxLimit:int = 10;
		private var discarded:int = 0;
		
		public function GEHDisplay() {
			x = 10;
			y = 10;
			
			title = new TextField();
			title.defaultTextFormat = new TextFormat("Arial", 48, 0xDBDBDB);
			//title.x = 10;
			title.text = "Internal runtime errors";
			title.autoSize = TextFieldAutoSize.LEFT;
			addChild(title);
			
			errorDisplay.y = 65;
			addChild(errorDisplay);
			
			buttonBar.addChild(continueBtn);
			buttonBar.addChild(dismissBtn);
			buttonBar.addChild(bugReportBtn);
			buttonBar.addChild(pastebinBtn);
			
			continueBtn.addEventListener(MouseEvent.CLICK, dispatch);
			dismissBtn.addEventListener(MouseEvent.CLICK, dispatch);
			bugReportBtn.addEventListener(MouseEvent.CLICK, dispatch);
			pastebinBtn.addEventListener(MouseEvent.CLICK, dispatch);
			
			addChild(buttonBar);
			
			
			
			var g:Graphics = discardedHighlight.graphics;
			g.clear();
			var m:Matrix = new Matrix();
			m.createGradientBox(207, 20);
			g.beginGradientFill(GradientType.LINEAR, [0xFFFF00, 0xFFFF00], [0, 0.5], [0, 200], m);
			//g.beginFill(0xFF000000);
			g.drawRoundRectComplex(0, 0, 207, 18, 8, 8, 8, 8);
			g.endFill();
			discardedHighlight.alpha = 0;
			addChild(discardedHighlight);
			
			discardedTxt = new TextField();
			discardedTxt.defaultTextFormat = new TextFormat("Arial", 11, 0x727272);
			discardedTxt.text = "";
			discardedTxt.width = 200;
			discardedTxt.autoSize = TextFieldAutoSize.RIGHT;
			addChild(discardedTxt);
			
			addEventListener(Event.ADDED_TO_STAGE, init);
			resize();
		}
		
		private function dispatch(e:MouseEvent):void {
			switch (e.target as GEHButton) {
				case continueBtn:	dispatchEvent(new Event(CONTINUE)); break;
				case dismissBtn:	dispatchEvent(new Event(DISMISS_ALL)); break;
				case bugReportBtn:	dispatchEvent(new Event(BUG_REPORT)); break;
				case pastebinBtn:	dispatchEvent(new Event(PASTEBIN)); break;
			}
		}
		
		private function init(e:Event):void {
			stage.addEventListener(Event.RESIZE, stageResize);
			stageResize();
		}
		
		private function stageResize(e:Event = null):void {
			w = stage.stageWidth-20;
			h = stage.stageHeight-20;
			resize();
		}
		
		public function getSelectedErrorTitle():String {
			if (selected) {
				return selected.title;
			} else return null;
		}
		public function getSelectedErrorText():String {
			if (selected) {
				return selected.text;
			} else return null;
		}
		
		public function addError(title:String, text:String):void {
			if (errors.length >= maxLimit) {
				addDiscarded();
				return;
			}
			
			var error:GEHError = new GEHError(title, text, w);
			error.addEventListener(GEHError.REPOSITION, reposition);
			error.addEventListener(GEHError.SELECTED, errorSelected);
			error.addEventListener(GEHError.REMOVE_ERROR, removeError);
			if (errors.length == 0) {
				selected = error;
				error.select();
			}
			errors.push(error);
			errorDisplay.addChild(error);
			reposition();
		}
		private function addDiscarded():void{
			discarded++;
			discardedTxt.text = discarded+(discarded == 1 ? " error" : " errors")+" discarded";
			discardedHighlight.alpha = 1;
			TweenNano.to(discardedHighlight, 3, { "overwrite": true, "delay": 5, "alpha": 0 } );
		}
		
		private function removeError(e:Event):void {
			var error:GEHError = e.target as GEHError;
			var index:int = errors.indexOf(error);
			errors.splice(index, 1);
			errorDisplay.removeChild(error);
			
			if (selected == error) {
				if (errors.length > 0) {
					index = Math.max(0, Math.min(errors.length-1, index));
					selected = errors[index];
					errors[index].select();
				} else {
					selected = null;
				}
			}
			if (errors.length == 0) {
				dispatchEvent(new Event(CONTINUE));
			}
			
			reposition();
		}
		
		private function errorSelected(e:Event):void {
			var error:GEHError = e.target as GEHError;
			if (selected && selected != error) {
				selected.deselect();
			}
			selected = error;
		}
		
		private function resize(e:Event = null):void {
			buttonBar.y = h-buttonBar.height;
			continueBtn.x = w-continueBtn.width;
			dismissBtn.x = continueBtn.x-dismissBtn.width-5;
			pastebinBtn.x = bugReportBtn.x+bugReportBtn.width+5;
			
			discardedTxt.x = w-discardedTxt.width-3;
			discardedTxt.y = buttonBar.y-18-3;
			discardedHighlight.x = discardedTxt.x+discardedTxt.width-discardedHighlight.width;
			discardedHighlight.y = discardedTxt.y;
			
			for (var i:int = 0; i < errors.length; i++) {
				var error:GEHError = errors[i];
				error.resize(w);
			}
		}
		private function reposition(e:Event = null):void {
			var y:Number = 0;
			for (var i:int = 0; i < errors.length; i++) {
				var error:GEHError = errors[i];
				error.y = y;
				y += error.h;
			}
		}
	}
}